﻿using System;
using System.Collections.Generic;
using System.Diagnostics.CodeAnalysis;
using System.Linq;
using System.Security.Principal;
using System.Web;
using System.Web.Mvc;
using System.Web.Routing;
using System.Web.Security;
using Defect_Tracking_System.Models;
using Defect_Tracking_System.Helpers;

namespace Defect_Tracking_System.Controllers
{

    [HandleError]
    public class AccountController : Controller
    {
        Utilities utilities = new Utilities();
        AccountManagement accountManagement = AccountManagement.GetInstance();
        DefectManagement DM = DefectManagement.GetInstance();

        protected override void Initialize(RequestContext requestContext)
        {
            base.Initialize(requestContext);
        }

        // **************************************
        // URL: /Account/LogOn
        // **************************************

        public ActionResult LogOn()
        {
            if (Request.IsAuthenticated)
            {
                return RedirectToAction("Index", "Defect");
            }
            return View();
        }

        [HttpPost]
        public ActionResult LogOn(LogOnModel model, string returnUrl)
        {
            
            if (ModelState.IsValid)
            {
                if (accountManagement.ValidateUser(model.UserName, model.Password))
                {
                    Account acc = accountManagement.GetUserByUserName(model.UserName);

                    if (acc.IsActive && acc.Group.IsActived)
                    {
                        FormsAuthentication.SetAuthCookie(model.UserName, model.RememberMe);

                        if (acc.Role == "System Admin")
                        {
                            returnUrl = null;
                        }
                        if (!String.IsNullOrEmpty(returnUrl))
                        {
                            return Redirect(returnUrl);
                        }
                        else
                        {
                            if (acc.Role != "System Admin")
                            {
                                return RedirectToAction("Index", "Defect");
                            }
                            else
                            {
                                return RedirectToAction("Index", "Group");
                            }
                        }
                    }
                    else
                    {
                        ModelState.AddModelError("", "Your account or group is disabled");
                    }
                }
                else
                {
                    ModelState.AddModelError("", "The user name or password is incorrect.");
                }
            }

            // If we got this far, something failed, redisplay form
            return View(model);
        }

        // **************************************
        // URL: /Account/LogOff
        // **************************************

        public ActionResult LogOff()
        {
            FormsAuthentication.SignOut();

            return RedirectToAction("Index", "Defect");
        }

        // **************************************
        // URL: /Account/Register
        // **************************************

        public ActionResult Register()
        {
            return View();
        }

        [HttpPost]
        public ActionResult Register(RegisterModel model)
        {
           
            if (ModelState.IsValid)
            {
                if (model.Password != model.ConfirmPassword)
                {
                    ViewData["message"] = "Confirm Password not match";
                }
                else
                {
                    Account account = accountManagement.GetUserByUserName(model.UserName);

                    if (account != null)
                    {
                        ViewData["message"] = "User Name is existed";
                    }
                    else
                    {
                        account = accountManagement.GetUserByEmail(model.Email);

                        if (account != null)
                        {
                            ViewData["message"] = "Email is existed";
                        }
                        else
                        {
                            try
                            {
                                accountManagement.Register(model);
                                FormsAuthentication.SetAuthCookie(model.UserName, false);
                                EmailSender.GetInstance().AddNewEmail(model.Email, "Defect Tracking System", "Thanks you to register in my System <br/>Your UserName : " + model.UserName + "<br/>Your Password: " + model.Password);
                                EmailSender.GetInstance().Send();
                                return RedirectToAction("Index", "Account");
                            }
                            catch (Exception ex)
                            {
                                ViewData["message"] = ex.Message;
                            }

                        }
                    }
                }
            }
            

            // If we got this far, something failed, redisplay form
            return View(model);
        }

        // **************************************
        // URL: /Account/ChangePassword
        // **************************************

        [Authorize]
        public ActionResult ChangePassword()
        {
            ChangePasswordModel Model = new ChangePasswordModel();

            Model.UserName = User.Identity.Name;

            return View(Model);
        }

        [Authorize]
        [HttpPost]
        public ActionResult ChangePassword(ChangePasswordModel Model)
        {
            Model.UserName = User.Identity.Name;

            if (ModelState.IsValid)
            {
                if (Model.NewPassword != Model.ConfirmPassword)
                {
                    ViewData["message"] = "Confirm Password not match";
                }
                else
                {
                    try
                    {
                        accountManagement.ChangePassword(Model);
                        ViewData["message"] = "Change password successfully";
                    }
                    catch (Exception ex)
                    {
                        ViewData["message"] = ex.Message;
                    }
                }
            }

            // If we got this far, something failed, redisplay form
            return View(Model);
        }

        // **************************************
        // URL: /Account/ForgotPassword
        // **************************************
        public ActionResult ForgotPassword()
        {
            ForgotPasswordModel Model = new ForgotPasswordModel();
            
            return View(Model);
        }

        [HttpPost]
        public ActionResult ForgotPassword(ForgotPasswordModel Model)
        {
            if (ModelState.IsValid)
            {
                try
                {
                    accountManagement.ResetPassword(Model.Email);
                    ViewData["message"] = "Reset password successfully";
                }
                catch(Exception ex)
                {
                    ViewData["message"] = ex.Message;
                }
            }
            return View(Model);
        }
        

        // **************************************
        // URL: /Account/ResetPassword
        // **************************************

        [Authorize(Roles = "Group Admin")]
        public ActionResult ResetPassword(String Email, String ReturnUrl)
        {
            Session["Message"] = null;
            try
            {
                accountManagement.ResetPassword(Email);
                Session["Message"] = "Reset password of " + Email + " is successful";
            }
            catch (Exception ex)
            {
                Session["Message"] = ex.Message;
            }

            if (ReturnUrl == null)
            {
                return RedirectToAction("Index");
            }
            return Redirect(ReturnUrl);
        }

        // **************************************
        // URL: /Account/Index
        // **************************************
        [Authorize(Roles="Group Admin")]
        public ActionResult Index(int PageIndex = 1)
        {

            string UserName = User.Identity.Name;

            PaginatedList<Account> Model = new PaginatedList<Account>(accountManagement.GetAccounts(UserName), PageIndex, 10);

            return View(Model);        
        }

        // **************************************
        // URL: /Account/Add
        // **************************************
        [Authorize(Roles = "Group Admin")]
        public ActionResult Add()
        {
            AddGroupMemberModel model = new AddGroupMemberModel();

            return View(model);
        }

        [HttpPost]
        [Authorize(Roles = "Group Admin")]
        public ActionResult Add(AddGroupMemberModel model) 
        {
            if (ModelState.IsValid)
            {
                if (model.Password != model.ConfirmPassword)
                {
                    ViewData["message"] = "Confirm Password not match";
                }
                else
                {
                    Account account = accountManagement.GetUserByUserName(model.UserName);

                    if (account != null)
                    {
                        ViewData["message"] = "User Name is existed";
                    }
                    else
                    {
                        account = accountManagement.GetUserByEmail(model.Email);

                        if (account != null)
                        {
                            ViewData["message"] = "Email is existed";
                        }
                        else
                        {
                            try
                            {
                                Account accountLogin = accountManagement.GetUserByUserName(User.Identity.Name);
                                model.GroupId = accountLogin.GroupId;
                                accountManagement.AddUser(model);
                                ViewData["message"] = "Add successfully";
                            }
                            catch (Exception ex)
                            {
                                ViewData["message"] = ex.Message;
                            }
                        }
                    }
                }
            }

            return View(model);
        }

        // **************************************
        // URL: /Account/Edit
        // **************************************
        [Authorize]
        public ActionResult Edit(String EditUser)
        {

            if (EditUser == null)
            {
                EditUser = User.Identity.Name;
            }
            else
            {
                Account accountLogin = accountManagement.GetUserByUserName(User.Identity.Name);
                if (accountLogin.Role != "Group Admin")
                {
                    ViewData["message"] = "You don't have permission to access this url";
                    return View("Error");
                }
            }

            EditGroupMemberModel model = accountManagement.GetGroupMemberModel(EditUser);

            return View(model);
        }
        
        [HttpPost]
        [Authorize]
        public ActionResult Edit(String EditUser, EditGroupMemberModel model)
        {
            if (EditUser == null)
            {
                EditUser = User.Identity.Name;
            }
            else
            {
                Account accountLogin = accountManagement.GetUserByUserName(User.Identity.Name);
                if (accountLogin.Role != "Group Admin")
                {
                    ViewData["message"] = "You don't have permission to access this url";
                    return View("Error");
                }
            }

            model.UserName = EditUser;

            if (ModelState.IsValid)
            {
                Account editAccount = accountManagement.GetUserByUserName(EditUser);

                if(editAccount.Profiles.FirstOrDefault().Email != model.Email)
                {
                    Account account = accountManagement.GetUserByEmail(model.Email);

                    if (account != null)
                    {
                        ViewData["message"] = "Email is existed";
                        return View(model);
                    }
                }

                try
                {
                    accountManagement.EditUser(model);
                    ViewData["message"] = "Edit successfully";
                }
                catch (Exception ex)
                {
                    ViewData["message"] = ex.Message;
                }
            }
            return View(model);
        }

        // **************************************
        // URL: /Account/Details
        // 
        [Authorize]
        public ActionResult Details(String UserName)
        {
            Account account = accountManagement.GetUserByUserName(UserName);
            
            return View(account);
        }

        // **************************************
        // URL: /Account/Delete
        // **************************************
        [Authorize(Roles = "Group Admin")]
        public ActionResult Delete(String UserName, String ReturnUrl)
        {
            Account account = accountManagement.GetUserByUserName(UserName);
            if (account == null)
            {
                Session["Message"] = "User not found";
                //return View("Error");
            }
            try
            {
                if (account.Role == "Group Admin")
                {
                    throw new Exception("You can't delete Group Admin");
                }

                accountManagement.DeleteUser(account.UserName.ToString());
                Session["Message"] = "User Deleted";
            }
            catch (Exception ex)
            {
                Session["Message"] = ex.Message;
            }

            return Redirect(ReturnUrl);
        }

        // **************************************
        // URL: /Account/Search
        // **************************************
        [Authorize]
        public ActionResult Search(String Keyword, int PageIndex = 1)
        {
            PaginatedList<Account> Model = null;
            Session["Message"] = null;
            try
            {
                var Query = accountManagement.SearchUser(Keyword, User.Identity.Name);
                Model = new PaginatedList<Account>(Query, PageIndex, 10);
            }
            catch (Exception ex)
            {
                ViewData["Message"] = ex.Message;
                return View("Error");
            }

            return View("Index", Model);
        }

        [Authorize]
        public ActionResult EmailNotificationSettings(String EditUser, String ReturnUrl)
        {
            ViewData["ReturnUrl"] = ReturnUrl;

            if (EditUser == null)
            {
                EditUser = User.Identity.Name;
            }
            else
            {
                Account accountLogin = accountManagement.GetUserByUserName(User.Identity.Name);

                if (accountLogin.Role != "Group Admin")
                {
                    ViewData["message"] = "You don't have permission to access this url";
                    return View("Error");
                }
            }

            EmailNotificationSettingsModel Model;

            try
            {
                Model = accountManagement.GetEmailNotificationSettingsModel(EditUser);
            }
            catch (Exception ex)
            {
                ViewData["Message"] = ex.Message;
                return View("Error");
            }

            return View(Model);
        }

        [Authorize, HttpPost]
        public ActionResult EmailNotificationSettings(String EditUser, FormCollection Forms)
        {

            if (EditUser == null)
            {
                EditUser = User.Identity.Name;
            }
            else
            {
                Account accountLogin = accountManagement.GetUserByUserName(User.Identity.Name);

                if (accountLogin.Role != "Group Admin")
                {
                    ViewData["message"] = "You don't have permission to access this url";
                    return View("Error");
                }
            }

            EmailNotificationSettingsModel Model;

            try
            {
                Model = accountManagement.GetEmailNotificationSettingsModel(EditUser);

                Model.SelectedCases = Forms.AllKeys;

                accountManagement.ChangeEmailNoficationSettings(Model);

                ViewData["Message"] = "Change Successfully";
            }
            catch (Exception ex)
            {
                ViewData["Message"] = ex.Message;
                return View("Error");
            }

            return View(Model);
        }
    }
}
